﻿#define _CRT_SECURE_NO_WARNINGS
//
//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _a;
//
//public:
//	Example(int a)
//	{
//		_a = a;
//	}
//};
//
//int main()
//{
//	//运算符我们可以直接用于内置类型
//	int x = 1;
//	int y = 2;
//	cout << "x + y = " << x + y << endl;
//
//	Example e1(4);
//	Example e2(5);
//	//err
//	//类类型对象使用运算符时,这个行为是编译器没有定义的
//	cout << "e1 + e2 = " << e1 + e2 << endl;
//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _x;
//	int _y;
//public:
//	//全缺省构造函数——也可以叫默认构造函数
//	Example(int x = 1, int y = 1)
//	{
//		_x = x;
//		_y = y;
//	}
//	//运算符重载==
//	//== 有两个操作对象，但是这里成员函数隐含一个this指针
//	//严格匹配规则，左侧运算对象传给第⼀个参数(this指针）
//	// 右侧运算对象传给第二个参数e
//	 bool operator== (const Example& e)
//	{
//		 return _x == e._x && _y == e._y;
//	}
//};
//
//int main()
//{
//	Example e1(1, 1);
//	Example e2(2, 2);
//	//运算符==重载
//	if (e1 == e2)
//	{
//		cout << "e1 == e2" << endl;
//	}
//	else
//	{
//		cout << "e1 != e2" << endl;
//	}
//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class Example
//{
//public:
//	int _x;
//	int _y;
//
//	//全缺省构造函数——也可以叫默认构造函数
//	Example(int x = 1, int y = 1)
//	{
//		_x = x;
//		_y = y;
//	}
//};
////运算符重载==（全局函数）
////== 有两个操作对象
////严格匹配规则，左侧运算对象传给第⼀个参数e1
////右侧运算对象传给第二个参数e2
////方法一：成员变量公有，类外就可以访问~
//bool operator==(const Example& e1, const Example& e2)
//{
//	return e1._x == e2._x && e1._y == e2._y;
//}
//int main()
//{
//	Example e1(1, 1);
//	Example e2(2, 2);
//	//运算符==重载
//	if (e1 == e2)
//	{
//		cout << "e1 == e2" << endl;
//	}
//	else
//	{
//		cout << "e1 != e2" << endl;
//	}
//	return 0;
//}

//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _x;
//	int _y;
//public:
//	//全缺省构造函数——也可以叫默认构造函数
//	Example(int x = 1, int y = 1)
//	{
//		_x = x;
//		_y = y;
//	}
//	//const加在后面，const修饰对象不被修改（后面会讲到）
//	int GetX()const
//	{
//		return _x;
//	}
//	//const加在后面，const修饰对象不被修改
//    int GetY()const
//	{
//		return _y;
//	}
//};
////运算符重载==（全局函数）
////== 有两个操作对象
////严格匹配规则，左侧运算对象传给第⼀个参数e1
////右侧运算对象传给第二个参数e2
//
////方法二：类里面提供get函数
//bool operator==(const Example& e1,const Example& e2)
//{
//	return (e1.GetX() == e2.GetX())&& (e1.GetY() == e2.GetY());
//}
//int main()
//{
//	Example e1(1, 1);
//	Example e2(2, 2);
//	
//	//运算符==重载
//	if (e1 == e2)
//	{
//		cout << "e1 == e2" << endl;
//	}
//	else
//	{
//		cout << "e1 != e2" << endl;
//	}
//	return 0;
//}

//
//#include<iostream>
//using namespace std;
//
//class Example
//{
//private:
//	int _x;
//	int _y;
//public:
//	//全缺省构造函数——也可以叫默认构造函数
//	Example(int x = 1, int y = 1)
//	{
//		_x = x;
//		_y = y;
//	}
//	//使用友元函数，友元函数类外可以访问私有成员
//	friend bool operator==(const Example& e1, const Example& e2);
//};
////运算符重载==（全局函数）
////== 有两个操作对象
////严格匹配规则，左侧运算对象传给第⼀个参数e1
////右侧运算对象传给第二个参数e2
//
////方法三：使用友元函数
////友元函数只需要在声明处加friend
//bool operator==(const Example& e1, const Example& e2)
//{
//	return e1._x == e2._x && e1._y == e2._y;
//}
//int main()
//{
//	Example e1(1, 1);
//	Example e2(2, 2);
//
//	//运算符==重载
//	if (e1 == e2)
//	{
//		cout << "e1 == e2" << endl;
//	}
//	else
//	{
//		cout << "e1 != e2" << endl;
//	}
//	return 0;
//}
//
//#include<iostream>
//using namespace std;
//typedef int STDataType;
//class Stack
//{
//public:
//	Stack(int n = 4)
//	{
//		_a = (STDataType*)malloc(sizeof(STDataType) * n);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败");
//			return;
//		}
//		_capacity = n;
//		_top = 0;
//	}
//	//涉及资源，需要显示写拷贝构造函数
//	Stack(const Stack& st)
//	{
//		// 需要对_a指向资源创建同样大的资源再拷贝
//		_a = (STDataType*)malloc(sizeof(STDataType) * st._capacity);
//		if (nullptr == _a)
//		{
//			perror("malloc申请空间失败!!!");
//			return;
//		}
//
//		memcpy(_a, st._a, sizeof(STDataType) * st._top);
//		_top = st._top;
//		_capacity = st._capacity;
//	}
//
//	void Push(STDataType x)
//	{
//		if (_top == _capacity)
//		{
//			int newcapacity = _capacity * 2;
//			STDataType* tmp = (STDataType*)realloc(_a, newcapacity *
//				sizeof(STDataType));
//			if (tmp == NULL)
//			{
//				perror("realloc fail");
//				return;
//			}
//			_a = tmp;
//			_capacity = newcapacity;
//		}
//		_a[_top++] = x;
//	}
//	//析构函数
//	~Stack()
//	{
//		cout << "~Stack()" << endl;
//		free(_a);
//		_a = nullptr;
//		_top = _capacity = 0;
//	}
//
//private:
//	STDataType* _a;
//	size_t _capacity;
//	size_t _top;
//};
//
//// 两个Stack实现队列
//class MyQueue
//{
//public:
//private:
//	Stack pushst;
//	Stack popst;
//};
//int main()
//{
//	Stack st1;
//	st1.Push(1);
//	st1.Push(2);
//	// 如果Stack不显示实现拷贝构造，那么会使用编译器自动生成的拷贝构造完成浅拷贝
//	// 会导致st1和st2⾥⾯的_a指针指向同⼀块资源，析构时会析构两次，程序崩溃
//
//	Stack st2 = st1;
//	MyQueue mq1;
//	// MyQueue自动生成的拷贝构造，会自动调用Stack拷贝构造完成pushst/popst
//	// 的拷贝，只要Stack拷贝构造实现了深拷贝，就没问题~
//	MyQueue mq2 = mq1;
//	return 0;
//}

//#include<iostream>
//using namespace std;
//class A
//{
//public:
//
//	void func()
//	{
//		cout << "func( )" << endl;
//	}
//};
//
////typedef void(*)() PF;//err 错误的重命名函数指针写法
////正确写法：名称与前面嵌套在一起
////因为是成员函数前面加A::
//typedef void(A::* PF)(); //成员函数指针类型
//
//int main()
//{
//	// C++规定成员函数要加&才能取到函数指针
//	PF pf = &A::func;
//	//A::func到类里面找func函数
//	//&A::func得到它的地址——成员函数指针
//
//	A obj;//定义A类对象obj
//	//(*pf)();//err //想要调用成员函数，有一个this指针
//	// 对象调用成员函数指针时，使⽤.*运算符
//	//先对pf解引用得到这个函数，调用对象的func函数
//	(obj.*pf)();
//	return 0;
//}


#include<iostream>
using namespace std;

class Example
{
private:
	int _x;
	int _y;
public:
	//构造函数
	Example(int x = 1, int y = 1)
	{
		_x = x;
		_y = y;
	}
	//前置++
	Example& operator++()
	{
		cout << "前置++" << endl;
		//先++再使用
		//也就是自己++后返回
		(*this)._x += 1;
		(*this)._y += 1;
		return *this;//返回使用引用减少拷贝次数
	}
	//后置++
	Example operator++(int)//后置++重载时，增加一个int形参
	{
		cout << "后置++" << endl;
		Example tmp = *this;
		//先使用再++
		(*this)._x += 1;
		(*this)._y += 1;
		return tmp;
		//不可以引用返回，tmp是临时对象，需要拷贝一份，避免后面销毁
	}
	//打印
	void Print()
	{
		cout << _x << "," << _y << endl;
	}
};
int main()
{
	Example e1(2, 2);
	Example e2(2, 2);
	//前置++
	Example e3 = ++e1;
	cout << "e3 = ++e1" << endl;
	e3.Print();
	//后置++
	Example e4 = e2++;
	cout << "e4 = e2++" << endl;
	e4.Print();

	cout << "e1" << endl;
	e1.Print();
	cout << "e2" << endl;
	e2.Print();
	return 0;
}